package com.xiangmo.travel.Service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiangmo.travel.Dto.AttractionCollectCountDto;
import com.xiangmo.travel.Dto.CollectDto;
import com.xiangmo.travel.Dvo.AttractionCollectCountDvo;
import com.xiangmo.travel.Dvo.CollectDvo;
import com.xiangmo.travel.Dvo.TableCollectDvo;
import com.xiangmo.travel.Entity.Attractions;
import com.xiangmo.travel.Entity.Collect;
import com.xiangmo.travel.Entity.Team;
import com.xiangmo.travel.Result.PageToListResult;
import com.xiangmo.travel.Service.CollectService;
import com.xiangmo.travel.mapper.AttractionsMapper;
import com.xiangmo.travel.mapper.CollectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CollectServiceImpl implements CollectService {
    @Autowired
    private CollectMapper collectMapper;
    @Autowired
    private AttractionsMapper attractionsMapper;

    @Override
    public Long getCollectNumByAttractionId(Long id) {
        LambdaQueryWrapper<Collect> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Collect::getAttractionsId, id);
        return collectMapper.selectCount(lambdaQueryWrapper);
    }

    @Override
    public PageToListResult<CollectDvo> getCollectListByUserId(int pageNum, int pageSize, Long id) {
        Page<Collect> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Collect> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Collect::getUserId, id);
        collectMapper.selectPage(page, lambdaQueryWrapper);
        List<Collect> list = page.getRecords();
        List<CollectDvo> dvoList = new ArrayList<>();
        for(Collect c : list){
            Attractions attractions = attractionsMapper.selectById(c.getAttractionsId());
            CollectDvo collectDvo = new CollectDvo();
            collectDvo.setAbout(attractions.getAbout());
            collectDvo.setImage(attractions.getImage());
            collectDvo.setUserId(c.getUserId());
            collectDvo.setAttractionsId(c.getAttractionsId());
            collectDvo.setTitle(attractions.getTitle());
            collectDvo.setCreatedAt(c.getCreatedAt());
            collectDvo.setType(attractions.getType());
            dvoList.add(collectDvo);
        }
        PageToListResult<CollectDvo> pageToListResult = new PageToListResult<>();
        pageToListResult.setList(dvoList);
        pageToListResult.setPages(page.getPages());
        pageToListResult.setPageCurrent(page.getCurrent());
        pageToListResult.setPageTotal(page.getTotal());
        pageToListResult.setSize(page.getSize());
        return pageToListResult;
    }

    @Override
    public int setCollect(CollectDto collectDto) {
        Collect collect = Collect.builder()
                .attractionsId(collectDto.getAttractionsId())
                .userId(collectDto.getUserId())
                .build();
        return collectMapper.insert(collect);
    }

    @Override
    public int deleteCollectById(Long userId, Long attractionsId) {
        return collectMapper.deleteByAttractionsIdAndUserId(attractionsId, userId);
    }

    @Override
    public int isCollectByUser(CollectDto collectDto) {
        LambdaQueryWrapper<Collect> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Collect::getUserId, collectDto.getUserId())
                .and(i -> i.eq(Collect::getAttractionsId, collectDto.getAttractionsId()));
        if(collectMapper.selectCount(lambdaQueryWrapper) >= 1L){
            return 1;
        }
        return 0;
    }

    @Override
    public List<AttractionCollectCountDvo> getTop10SpotByCollectCount() {
        QueryWrapper<Collect> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("attractions_id", "count(DISTINCT id) as total")
                .groupBy("attractions_id")
                .orderByDesc("total")
                .last("LIMIT 10");
        //使用Stream API 对集合进行处理和操作
        List<AttractionCollectCountDto> attractionCollectCountDto = collectMapper.selectMaps(queryWrapper).stream()
                .map(item -> {
                    AttractionCollectCountDto dto = new AttractionCollectCountDto();
                    dto.setAttractionId((Long) item.get("attractions_id"));
                    dto.setTotal((Long) item.get("total"));
                    return dto;
                }).collect(Collectors.toList());
        attractionCollectCountDto.forEach(System.out::println);
        List<AttractionCollectCountDvo> result = new ArrayList<>();
        for (AttractionCollectCountDto a : attractionCollectCountDto) {
            AttractionCollectCountDvo attractionCollectCountDvo = new AttractionCollectCountDvo();
            System.out.println(a.getAttractionId());
            Attractions attractions = attractionsMapper.selectById(a.getAttractionId());

            attractionCollectCountDvo.setAttractionId(a.getAttractionId());
            attractionCollectCountDvo.setTotal(a.getTotal());
            attractionCollectCountDvo.setAbout(attractions.getAbout());
            attractionCollectCountDvo.setImage(attractions.getImage());
            attractionCollectCountDvo.setTitle(attractions.getTitle());
            result.add(attractionCollectCountDvo);
        }
        return result;
    }

    @Override
    public List<TableCollectDvo> getTop6CollectById(Long id) {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 获取六天前的时间
        LocalDateTime sixDaysBefore = now.minusDays(6);
        // 构建查询条件
        QueryWrapper<Collect> wrapper = new QueryWrapper<>();
        wrapper.select("DATE(created_at) as created_at", "count(*) as count")
                .eq("attractions_id", id)
                .between("created_at", sixDaysBefore, now)
                .groupBy("DATE(created_at)")
                .orderByDesc("created_at");
        // 执行查询
        List<Map<String, Object>> result = collectMapper.selectMaps(wrapper);
        // 封装结果
        List<TableCollectDvo> vos = new ArrayList<>();
        for (int i = 0; i < 6; i++) {
            TableCollectDvo vo = new TableCollectDvo();
            LocalDate currentDate = LocalDate.now().minusDays(i);
            vo.setCreatedAt(currentDate.toString());
            vo.setCount(0L);
            for (Map<String, Object> map : result) {
                LocalDate dateInMap = ((java.sql.Date) map.get("created_at")).toLocalDate();
                if (currentDate.equals(dateInMap)) {
                    vo.setCount((Long) map.get("count"));
                    break;
                }
            }
            vos.add(vo);
        }
        return vos;
    }

}
